#include "beatslistmodel.h"

BeatsListModel::BeatsListModel(QObject* parent)
    : QAbstractListModel(parent)
{
    // beatsModel.saveQHashToBinaryFile();
    // beatsModel.loadQHashFromBinaryFile();
    // QVector<int> result = beatsModel.getFragmentBeats(0, 10000);
    // qDebug() << result;
    // QVector<int> result = beatsModel.getFragmentBeats(0, 0);
    // for (int i = 0; i < result.size(); ++i) {
    //     m_data.append(BeatsData(result[i],"N"));
    // }
}

int BeatsListModel::rowCount(const QModelIndex& parent) const
{
    // For list models only the root node (an invalid parent) should return the list's size. For all
    // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
    if (parent.isValid())
        return 0;

    // FIXME: Implement me!
    return m_data.size();
}

QVariant BeatsListModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid())
        return QVariant();
    const auto& item = m_data.at(index.row());
    if (role == rPeaksInAllRole)
        return item.rPeaksInAll;
    else if (role == labelRole)
        return item.label;
    else if (role == rrIntervalsRole)
        return item.rrIntervals;
    else if (role == selectedRole)
        return item.selected;
    else if (role == qOffsetRole)
        return item.qOffset;
    else if (role == sOffsetRole)
        return item.sOffset;
    else if (role == test1Role)
        return item.test1;
    else if (role == test2Role)
        return item.test2;
    else if (role == test3Role)
        return item.test3;
    else if (role == test4Role)
        return item.test4;
    else if (role == test5Role)
        return item.test5;
    else if (role == test6Role)
        return item.test6;
    else if (role == test7Role)
        return item.test7;
    else if (role == test8Role)
        return item.test8;
    else if (role == test9Role)
        return item.test9;
    else if (role == test10Role)
        return item.test10;
    return QVariant();
}

QHash<int, QByteArray> BeatsListModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[rPeaksInAllRole] = "rPeaksInAll";
    roles[labelRole] = "label";
    roles[rrIntervalsRole] = "rrIntervals";
    roles[selectedRole] = "selected";
    roles[qOffsetRole] = "qOffset";
    roles[sOffsetRole] = "sOffset";
    roles[test1Role] = "test1";
    roles[test2Role] = "test2";
    roles[test3Role] = "test3";
    roles[test4Role] = "test4";
    roles[test5Role] = "test5";
    roles[test6Role] = "test6";
    roles[test7Role] = "test7";
    roles[test8Role] = "test8";
    roles[test9Role] = "test9";
    roles[test10Role] = "test10";
    return roles;
}

BeatsListModel::MyRoles BeatsListModel::getRPeaksInAllRole()
{
    return rPeaksInAllRole;
}

BeatsListModel::MyRoles BeatsListModel::getLabelRole()
{
    return labelRole;
}

void BeatsListModel::getFragmentBeats(int start, int duration)
{
    // int sampleRate = ecg.sampleRate();
    if (start < 0) {
        start = 0;
    }

    beginResetModel();
    m_data.clear();
    QVector<int> result = beatsModel.getFragmentBeats(start, duration);
    for (int i = 0; i < result.size(); ++i) {
        QHash beatLabel = beatsModel.labels[beatsModel.data[result[i]][beatsModel.labelIndex]];
        int16_t rrIntervals = beatsModel.data[result[i]][beatsModel.rrIntervalsIndex];
        int16_t selected = beatsModel.data[result[i]][beatsModel.selectedIndex];
        int16_t qOffset = beatsModel.data[result[i]][beatsModel.qIndex];
        int16_t sOffset = beatsModel.data[result[i]][beatsModel.sIndex];
        int16_t test1 = beatsModel.data[result[i]][beatsModel.test1Index];
        int16_t test2 = beatsModel.data[result[i]][beatsModel.test2Index];
        int16_t test3 = beatsModel.data[result[i]][beatsModel.test3Index];
        // qDebug() << rrIntervals;
        m_data.append(BeatsData(result[i], beatLabel.value("label"), rrIntervals, selected,qOffset,sOffset,test1,test2,test3));
    }
    endResetModel();
    setBeatsCount(m_data.size());
}

void BeatsListModel::refreshMData(QVector<int> rPeaksInAlls)
{
    for (int i = 0; i < m_data.size(); ++i) {
        int rPeaksInAll = m_data[i].rPeaksInAll;
        if (rPeaksInAlls.contains(rPeaksInAll)) {
            QHash beatLabel = beatsModel.labels[beatsModel.data[rPeaksInAll][beatsModel.labelIndex]];
            int16_t rrIntervals = beatsModel.data[rPeaksInAll][beatsModel.rrIntervalsIndex];
            int16_t selected = beatsModel.data[rPeaksInAll][beatsModel.selectedIndex];
            m_data[i].label = beatLabel.value("label");
            m_data[i].rrIntervals = rrIntervals;
            m_data[i].selected = selected;
            emit dataChanged(this->index(i, 0), this->index(i, 0),{labelRole,rrIntervalsRole,selectedRole});
        }
    }
}

void BeatsListModel::refreshListInBeatsModelData()
{
    beginResetModel();
    m_data.clear();

    for (int i = 0; i < beatsModel.listBeats.size(); ++i) {
        QHash beatLabel = beatsModel.labels[beatsModel.data[beatsModel.listBeats[i]][beatsModel.labelIndex]];
        int16_t rrIntervals = beatsModel.data[beatsModel.listBeats[i]][beatsModel.rrIntervalsIndex];
        int16_t selected = beatsModel.data[beatsModel.listBeats[i]][beatsModel.selectedIndex];
        // qDebug() << rrIntervals;
        m_data.append(BeatsData(beatsModel.listBeats[i], beatLabel.value("label"), rrIntervals, selected));
    }
    endResetModel();
    setBeatsCount(m_data.size());
}

void BeatsListModel::refreshListInBeatsModelCircleSelectBeats()
{
    beginResetModel();
    m_data.clear();

    for (int i = 0; i < beatsModel.circleSelectBeats.size(); ++i) {
        QHash beatLabel = beatsModel.labels[beatsModel.data[beatsModel.circleSelectBeats[i]][beatsModel.labelIndex]];
        int16_t rrIntervals = beatsModel.data[beatsModel.circleSelectBeats[i]][beatsModel.rrIntervalsIndex];
        int16_t selected = beatsModel.data[beatsModel.circleSelectBeats[i]][beatsModel.selectedIndex];
        // qDebug() << rrIntervals;
        m_data.append(BeatsData(beatsModel.circleSelectBeats[i], beatLabel.value("label"), rrIntervals, selected));
    }
    endResetModel();
    setBeatsCount(m_data.size());
}

int BeatsListModel::getBeatsCount() const
{
    return beatsCount;
}

void BeatsListModel::setBeatsCount(int newBeatsCount)
{
    if (beatsCount == newBeatsCount)
        return;
    beatsCount = newBeatsCount;
    emit beatsCountChanged();
}
